#!/usr/bin/env node
const path = require('path');
const fs = require('fs');
const { program } = require('commander');
const { execSync } = require('child_process');
const { exit } = require('process');

console.log(`开始发布模板代码......`);
console.group('STAGE1:校验发布模板参数');
const staticPath = path.resolve(path.join(__dirname, '../static'));
const templatePath = path.resolve(path.join(__dirname, '../template'));
program
  .option('-m, --model <model-path>', '模型目录')
  .option('-o, --output <output-path>', '输出目录, 默认输出: 模板目录/out')
  .option('--app [app-code-name]', '发布模式改为应用, 模型目录将识别为应用')
  .option(
    '-tv, --template-version <template-version>',
    '使用发布的模版包的版本号',
    'latest',
  )
  .option('--local-mode', '是否为本地模式', false)
  .parse(process.argv);
const { model, output, app, templateVersion, localMode } = program.opts();
console.log(`静态资源路径：${staticPath}`);
console.log(`模板资源路径：${templatePath}`);
console.log(`模型资源路径：${model}`);
console.log(`发布文件输出路径：${output}`);
console.log(`发布应用代码名称：${app}`);
console.log(`发布应用模板版本：${templateVersion}`);
console.log(`是否为本地模式：${localMode}`);
console.groupEnd('STAGE1:校验发布模板参数');


function isPackageInstalled(packageName, version) {
  try {
    const result = execSync(`npm list -g ${packageName} --depth=0 --json`, { encoding: 'utf-8' });
    const packages = JSON.parse(result);
    const installedVersion = packages.dependencies?.[packageName]?.version;
    return installedVersion === version;
  } catch (error) {
    return false;
  }
}

console.group(`STAGE2:校验发布模板${templateVersion}是否安装`);
const isInstalled = isPackageInstalled('@ibiz-template/full-code-template', templateVersion);
console.log(`@ibiz-template/full-code-template@${templateVersion}${isInstalled ? '已经安装' : '未安装'}`);
console.groupEnd(`STAGE2:校验发布模板${templateVersion}是否安装`);

// 未安装指定版本则安装指定版本@ibiz-template/full-code-template
if (!isInstalled) {
  console.group(`STAGE3:安装发布模板${templateVersion}`);
  try {
    execSync('npm i -g @ibiz-template/full-code-template@' + templateVersion);
    console.log(`安装@ibiz-template/full-code-template@${templateVersion}成功`);
  } catch (error) {
    console.error(`安装@ibiz-template/full-code-template@${templateVersion}失败`, error);
    exit(1)
  }
  console.groupEnd(`STAGE3:安装发布模板${templateVersion}`);
}

console.group(`STAGE${!isInstalled ? '4' : '3'}:发布代码`);

// 计算命令参数字符串
let commandParamStr = `-m ${model} -o ${output} --app ${app}`;
if(localMode){
  commandParamStr = `-m ${model} -o ${output} --app ${app} --local-mode`
}

try {

  execSync(`code-generator ${commandParamStr}`);
  console.log(`发布代码成功`);
} catch (error) {
  // code-generator 未找到时，则手动找到指定文件再执行发布代码逻辑
  // code-generator: not found
  if (error.status === 127) {
    const rootNpmPath = execSync(`npm root -g`, { encoding: 'utf-8' }).trim();
    const fullCodePath = path.resolve(path.join(rootNpmPath, '@ibiz-template/full-code-template'));
    const data = fs.readFileSync(path.join(fullCodePath, 'package.json'), 'utf8');
    const fullCodePackageJson = JSON.parse(data);
    const packageBinPath = fullCodePackageJson.bin['code-generator'];
    const fullCodeBinPath = path.resolve(path.join(fullCodePath, packageBinPath));
    if (fullCodeBinPath) {
      execSync(`node ${fullCodeBinPath} ${commandParamStr}`);
      console.log(`发布代码成功`);
    } else {
      console.error('发布代码失败', error);
      exit(1)
    }
  } else {
    console.error('发布代码失败', error);
    exit(1)
  }
}
console.groupEnd(`STAGE${!isInstalled ? '4' : '3'}:发布代码`);
console.log(`结束发布模板代码......`);